package com.haibo.utils;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author : 刘海波
 * @Date: 2024/10/12 10:16
 * @Description: 时间日期工具类
 */
@Slf4j
public class MyDateUtil {

    private static final Pattern ID_CARD_PATTERN = Pattern.compile("^\\d{17}[\\dXx]$");

    // ======================== 【获取下一个准点时间】 ==================
    /**
     * 获取dateStr的下一个准点时间，dateStr的格式为：yyyy-MM-dd HH:mm:ss
     * 例如：当前时间是2025-08-05 18:27:36，则下一个准点时间为19:00:00
     * @return
     */
    public static LocalDateTime getNextCompleteHour(String dateStr) throws Exception {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        try {
            // 解析输入的时间字符串为LocalDateTime对象
            LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);

            // 计算下一个准点时间
            // 如果当前时间正好是准点，返回下一个小时的准点
            if (dateTime.getMinute() == 0 && dateTime.getSecond() == 0) {
                return dateTime.plusHours(1).truncatedTo(ChronoUnit.HOURS);
            }

            // 否则，返回当前小时的下一个整点
            return dateTime.plusHours(1).truncatedTo(ChronoUnit.HOURS);

        } catch (Exception e) {
            throw new IllegalArgumentException("时间格式不正确，请使用'yyyy-MM-dd HH:mm:ss'格式", e);
        }
    }

    /**
     * 获取当前时间的下一个准点时间
     * 例如：当前时间是2025年8月5日18:17:57，则下一个准点时间为19:00:00
     * @return
     */
    public static LocalDateTime getNextCompleteHour() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 计算当前分钟数和秒数
        int minutes = now.getMinute();
        int seconds = now.getSecond();
        int nanos = now.getNano();

        // 如果当前正好是准点，直接加1小时
        if (minutes == 0 && seconds == 0 && nanos == 0) {
            return now.plusHours(1).truncatedTo(ChronoUnit.HOURS);
        }

        // 否则，将时间调整到下一个整点
        return now.plusHours(1).truncatedTo(ChronoUnit.HOURS);
    }

    // ========================= 【字符串转换为时间戳】 =========================

    /**
     * 将【yyyy-MM-dd】格式的字符串日期转换为时间戳
     * @param dateStr 格式形如：2025-07-28
     * @return
     */
    public static Long format1StringDate2TimeStamp(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return 0L;
        }

        dateStr = dateStr.trim();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(dateStr);
            long timestamp = date.getTime();
            return timestamp;
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return 0L;
    }

    // ========================= 【身份证号转换为yyyy-MM-dd格式的生日】 =========================
    /**
     * 从18位身份证号码中提取生日并转换为yyyy-MM-dd格式
     * @param idCard 18位身份证号码
     * @return 格式化的生日字符串，如果身份证格式错误则返回null
     */
    public static String extractBirthday(String idCard) {
        if (idCard == null || !ID_CARD_PATTERN.matcher(idCard).matches()) {
            return null;
        }
        try {
            String year = idCard.substring(6, 10);
            String month = idCard.substring(10, 12);
            String day = idCard.substring(12, 14);
            LocalDate birthday = LocalDate.of(
                    Integer.parseInt(year),
                    Integer.parseInt(month),
                    Integer.parseInt(day)
            );
            return birthday.format(DateTimeFormatter.ISO_LOCAL_DATE);
        } catch (Exception e) {
            return null;
        }
    }

    // ========================= 【StringDate转换为LocalDate】 =========================
    /**
     * 将【yyyy-MM-dd HH:mm:ss】格式的字符串日期转换为LocalDate
     * @param dateStr，日期：格式形如：2000-01-01 12:00:36
     * @return
     */
    public static LocalDate format1StringDate2LocalDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 将字符串解析为 LocalDateTime 对象
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        // 获取 LocalDate 对象
        LocalDate localDate = localDateTime.toLocalDate();

        return localDate;
    }

    /**
     * 将【yyyy/M/d H:m:s】格式的字符串日期转换为LocalDate
     * @param dateStr，日期：格式形如：2000-01-01 12:00:36
     * @return
     */
    public static LocalDate format2StringDate2LocalDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d H:m:s");

        // 将字符串解析为 LocalDateTime 对象
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        // 获取 LocalDate 对象
        LocalDate localDate = localDateTime.toLocalDate();

        return localDate;
    }

    /**
     * 将【yyyy-MM-dd】格式的字符串日期转换为LocalDate
     * @param dateStr，日期：格式形如：2000-01-01
     * @return
     */
    public static LocalDate format3StringDate2LocalDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        // 解析字符串为 LocalDate
        return LocalDate.parse(dateStr, formatter);
    }

    /**
     * 将【yyyy-MM-dd HH:mm】格式的字符串日期转换为LocalDate
     * @param dateStr，日期：格式形如：2000-01-01 08:00
     * @return
     */
    public static LocalDate format4StringDate2LocalDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

        // 1. 先解析为LocalDateTime
        LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);

        // 2. 提取日期部分
        LocalDate localDate = dateTime.toLocalDate();

        return localDate;
    }

    /**
     * 将【yyyy/MM/dd】格式的字符串日期转换为LocalDate
     * @param dateStr，日期：格式形如：2000/01/01
     * @return
     */
    public static LocalDate format5StringDate2LocalDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        // 解析字符串为 LocalDate
        return LocalDate.parse(dateStr, formatter);
    }

    // ========================= 【StringDate转换为年龄】 =========================
    /**
     * 将【yyyy-MM-dd HH:mm:ss】格式的字符串日期转换为年龄
     * @param birthday 生日，格式形如：2000-01-01 12:36:35
     * @return
     */
    public static long format1StringBirthday2Age(String birthday) {
        if (StringUtils.isBlank(birthday)) {
            return 0;
        }
        birthday = birthday.trim();
        // 定义日期格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
        // 将字符串解析为LocalDateTime对象
        LocalDateTime formattedBirthday = LocalDateTime.parse(birthday, formatter);
        // 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();
        // 计算年龄
        Period period = Period.between(formattedBirthday.toLocalDate(), now.toLocalDate());
        return period.getYears();
    }

    /**
     * 将【yyyyMMdd】格式的字符串日期转换为年龄
     * @param birthday 生日，格式形如：20000101
     * @return
     */
    public static long format2StringBirthday2Age(String birthday) {
        if (StringUtils.isBlank(birthday)) {
            return 0;
        }
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 将字符串转换为 LocalDate 对象
        LocalDate birthdayLocalDate = LocalDate.parse(birthday, formatter);
        // 获取当前日期
        LocalDate now = LocalDate.now();
        // 计算年龄
        Period period = Period.between(birthdayLocalDate, now);
        // 返回年龄
        return period.getYears();
    }

    /**
     * 将【yyyy-MM-dd】格式的字符串日期转换为年龄
     * @param birthday 生日，格式形如：2000-01-01
     * @return
     */
    public static long format3StringBirthday2Age(String birthday) {
        if (StringUtils.isBlank(birthday)) {
            return 0;
        }
        birthday = birthday.trim();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 解析字符串为LocalDate
        LocalDate birthDate = LocalDate.parse(birthday, formatter);
        LocalDate currentDate = LocalDate.now();

        // 计算年龄
        return ChronoUnit.YEARS.between(birthDate, currentDate);
    }

    // ========================= 【StringDate转换为LocalDateTime】 =========================
    /**
     * 将【yyyy-MM-dd HH:mm:ss】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：2024-12-05 13:02:00
     * @return
     */
    public static LocalDateTime format1StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        return localDateTime;
    }

    /**
     * 将【yyyy-MM-dd'T'HH:mm:ss】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：2025-03-25T12:00:01
     * @return
     */
    public static LocalDateTime format2StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        return localDateTime;
    }

    /**
     * 将【yyyyMMddHHmmss】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：20250507100000
     * @return
     */
    public static LocalDateTime format3StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        return localDateTime;
    }

    /**
     * 将【yyyy-MM-dd HH:mm:ss】格式 or【yyyy-MM-dd H:mm:ss】 or 【yyyy-MM-dd】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：20250507100000
     * @return
     */
    public static LocalDateTime format4StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }

        LocalDateTime localDateTime = null;
        List<DateTimeFormatter> dateTimeFormatters = Arrays.asList(
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
                DateTimeFormatter.ofPattern("yyyy-MM-dd H:mm:ss")
        );

        for (int i = 0; i < dateTimeFormatters.size(); i++) {
            try {
                localDateTime = LocalDateTime.parse(dateStr,dateTimeFormatters.get(i));
            } catch (DateTimeParseException e) {
                localDateTime = LocalDateTime.parse(dateStr,dateTimeFormatters.get(i+1));
            }
        }

        return localDateTime;
    }

    /**
     * 将【yyyy-MM-dd】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：20250507100000
     * @return
     */
    public static LocalDateTime format5StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;

        // 解析字符串为 LocalDate
        LocalDate localDate = LocalDate.parse(dateStr, formatter);

        // 将 LocalDate 转换为 LocalDateTime（默认时间为 00:00:00）
        LocalDateTime localDateTime = localDate.atStartOfDay();

        return localDateTime;
    }

    /**
     * 将【yyyy/MM/dd HH:mm:ss】 or 【yyyy/MM/dd】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：
     * @return
     */
    public static LocalDateTime format6StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();

        // 构建支持两种格式的解析器
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                // 基础日期格式：yyyy/MM/dd
                .appendPattern("yyyy/MM/dd")
                // 可选的时间部分：HH:mm:ss（若存在则解析，不存在则默认00:00:00）
                .optionalStart()
                .appendPattern(" HH:mm:ss")
                .optionalEnd()
                // 设置时间默认值（若未解析到时间，默认0时0分0秒）
                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                .toFormatter();

        // 解析字符串为LocalDateTime
        return LocalDateTime.parse(dateStr, formatter);
    }

    /**
     * 将【yyyy-MM-dd HH:mm】格式的字符串日期转换为LocalDateTime
     * @param dateStr 日期，格式形如：2025-07-01 08:36
     * @return
     */
    public static LocalDateTime format7StringDate2LocalDateTime(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();

        // 定义格式器，指定字符串的日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

        // 解析字符串为LocalDateTime对象
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        return localDateTime;
    }



    // ========================= 【StringDate转换为StringDate】 =========================

    /**
     * 将【yyyy-MM-dd HH:mm:ss.SSS】格式的字符串日期转换为【yyyy-MM-dd】格式的字符串日期
     * @param dateStr
     * @return
     */
    public static String format1StringDate2StringDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        SimpleDateFormat inputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        SimpleDateFormat outSdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date inputDate = inputSdf.parse(dateStr);
            String outputDate = outSdf.format(inputDate);
            return outputDate;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将【yyyy/M/d H:m:s】格式的字符串日期转换为【yyyyMMdd】格式的字符串日期
     * @param dateStr 格式形如：1997/5/18 0:00:00
     * @return
     */
    public static String format2StringDate2StringDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy/M/d H:m:s");
        SimpleDateFormat outputFormat = new SimpleDateFormat("yyyyMMdd");
        try {
            String patientBirthday = outputFormat.format(inputFormat.parse(dateStr));
            return patientBirthday;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将【yyyy-MM-dd HH:mm-ss】格式的字符串日期转换为【yyyy-MM-dd HH:mm:ss】格式的字符串日期
     * @param dateStr 2025-07-05 10:00-00 转换为 2025-07-05 10:00:00
     * @return
     */
    public static String format3StringDate2StringDate(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        dateStr = dateStr.trim();
        String prefix = dateStr.substring(0,16);
        String suffix = ":00";

        return prefix + suffix;
    }

    // ========================= 【StringDate转换为时间戳】 =========================

    /**
     * 将【yyyy-MM-dd HH:mm:ss.SSS】格式的字符串日期转换为时间戳
     * @param dateStr
     * @return
     */
    public static Long format1StringDate2Timestamp(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return 0L;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        try {
            Date date = sdf.parse(dateStr);
            long timestamp = date.getTime();
            return timestamp;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将【yyyy-MM-ddHH:mm:ss.SSS】格式的字符串日期转换为时间戳
     * @param dateStr
     * @return
     */
    public static Long format2StringDate2Timestamp(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return 0L;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss.SSS");
        try {
            Date date = sdf.parse(dateStr);
            long timestamp = date.getTime();
            return timestamp;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // ==================== 【LocalDateTime转StringDate】 ====================
    /**
     * 将LocalDateTime转换为【yyyy-MM-dd HH:mm:ss】格式的字符串日期
     * @param localDateTime
     * @return
     */
    public static String format1LocalDateTime2StringDate(LocalDateTime localDateTime) {
        if (ObjectUtil.isNull(localDateTime)) {
            return "";
        }
        String formattedTime = "";

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        formattedTime = formatter.format(localDateTime);

        return formattedTime;
    }

    /**
     * 将LocalDateTime转换为【yyyyMMddHHmmss】格式的字符串日期
     * @param localDateTime
     * @return
     */
    public static String format2LocalDateTime2StringDate(LocalDateTime localDateTime) {
        if (ObjectUtil.isNull(localDateTime)) {
            return "";
        }
        String formattedTime = "";

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        formattedTime = formatter.format(localDateTime);

        return formattedTime;
    }

    // ==================== 根据当前日期增加一天 ====================

    /**
     * 根据当前日期增加一天
     * @param originalDateStr 原始日期字符串，格式形如：Sun Jun 02 00:00:00 CST 2024
     * @return 增加后的日期，格式形如：2024-07-01
     */
    public static String addDay(String originalDateStr) {
        String newDateStr = "";
        // 创建 SimpleDateFormat 对象来解析日期字符串
        SimpleDateFormat sdf1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",Locale.ENGLISH);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");

        try {
            // 解析日期字符串为 Date 对象
            Date originalDate = sdf1.parse(originalDateStr);

            // 创建 Calendar 对象并设置为原始日期
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(originalDate);

            // 增加一天
            calendar.add(Calendar.DAY_OF_MONTH, 1);

            // 获取增加一天后的日期
            Date newDate = calendar.getTime();

            // 格式化新日期为字符串
            newDateStr = sdf2.format(newDate);

            // 输出结果
//            System.out.println("原始日期: " + originalDateStr);
//            System.out.println("增加一天后的日期: " + newDateStr);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return newDateStr;
    }

    // ==================== StringDate转Date ====================
    /**
     * 将【yyyyMMdd】类型的字符串日期转换为Date
     * @param dateStr
     * @return
     */
    public static Date format1StringDate2Date(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        return date;
    }

    /**
     * 将【yyyy-MM-dd】类型的字符串日期转换为Date
     * @param dateStr
     * @return
     */
    public static Date format2StringDate2Date(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        return date;
    }

    /**
     * 将【yyyyMMdd】类型的字符串日期转换为Date
     * @param dateStr
     * @return
     */
    public static Date format3StringDate2Date(String dateStr) {
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        return date;
    }

    // ==================== Date转StringDate ====================

    /**
     * 将Date类型的日期转换为【yyyyMMdd】格式的StringDate
     * @param date
     * @return
     */
    public static String format1Date2StringDate(Date date) {
        if (ObjectUtil.isNull(date)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(date);

        return dateStr;
    }

    /**
     * 将Date类型的日期转换为【yyyy-MM-dd】格式的StringDate
     * @param date
     * @return
     */
    public static String format2Date2StringDate(Date date) {
        if (ObjectUtil.isNull(date)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = sdf.format(date);

        return dateStr;
    }

    /**
     * 将Date类型的日期转换为【yyyy-MM-dd HH:mm:ss】格式的StringDate
     * @param originalDate
     * @return
     */
    public static String format3Date2StringDate(Date originalDate) {
        if (ObjectUtil.isNull(originalDate)) {
            return null;
        }
        String formattedDateString = "";
        // 原始日期字符串
        // String originalDateString = "Fri May 31 23:30:00 CST 2024";
        String originalDateString = originalDate.toString();

        // 定义原始日期格式
        SimpleDateFormat originalFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);

        // 定义目标日期格式
        SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            // 将原始日期字符串解析为 Date 对象
            Date date = originalFormat.parse(originalDateString);

            // 将 Date 对象格式化为目标格式
            formattedDateString = targetFormat.format(date);

            // 输出结果
            System.out.println("Original Date String: " + originalDateString);
            System.out.println("Formatted Date String: " + formattedDateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return formattedDateString;
    }

    /**
     * 将Date类型的日期转换为【yyyyMMdd HH:mm:ss】格式的StringDate
     * @param originalDate
     * @return
     */
    public static String format4Date2StringDate(Date originalDate) {
        if (ObjectUtil.isNull(originalDate)) {
            return null;
        }
        String formattedDateString = "";
        // 原始日期字符串
        // String originalDateString = "Fri May 31 23:30:00 CST 2024";
        String originalDateString = originalDate.toString();

        // 定义原始日期格式
        SimpleDateFormat originalFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);

        // 定义目标日期格式
        SimpleDateFormat targetFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss");

        try {
            // 将原始日期字符串解析为 Date 对象
            Date date = originalFormat.parse(originalDateString);

            // 将 Date 对象格式化为目标格式
            formattedDateString = targetFormat.format(date);

            // 输出结果
            System.out.println("Original Date String: " + originalDateString);
            System.out.println("Formatted Date String: " + formattedDateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return formattedDateString;
    }

    // ==================== 计算两个日期之间的差值，得到的天数 ============================

    /**
     * 计算两个【yyyy-MM-dd'T'HH:mm:ss】格式的字符串日期之间相差的天数
     * @param beginDate 开始时间，格式形如：2025-03-26T13:37:20
     * @param endDate   结束时间，格式形如：2025-04-01T10:15:30
     * @return
     */
    public static Long computeDays1(String beginDate,String endDate) {
        if (StringUtils.isBlank(beginDate) || StringUtils.isBlank(endDate)) {
            return 0L;
        }

        beginDate = beginDate.trim().substring(0,19);
        endDate = endDate.trim().substring(0,19);

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

        // 解析日期字符串为LocalDateTime对象
        LocalDateTime beginLocalDateTime = LocalDateTime.parse(beginDate,formatter);
        LocalDateTime endLocalDateTime = LocalDateTime.parse(endDate,formatter);

        // 计算两个日期之间的差值
        Duration duration = Duration.between(beginLocalDateTime, endLocalDateTime);

        // 获取相差的天数
        long daysBetween = duration.toDays();

        return daysBetween;
    }

    // ==================== 根据ES中的最大reportTime计算最近的整点信息 ====================
    /**
     * 根据ES中的最大reportTime计算最近的日期区间
     * @param esMaxReportTime ES中的最大reportTime
     * @param map
     * @return
     */
    public static Map<String,String> calculateJobDateRange(String esMaxReportTime, Map<String,String> map) {
        String newFrom = "";
        String newTo = "";

        if (StringUtils.isBlank(esMaxReportTime)) {
            return null;
        }

        String[] splits = esMaxReportTime.split(" ");
        // 年-月-日
        String from = splits[0];
        // 时:分:秒
        String to = splits[1];
        // 时
        String hour = to.split(":")[0];
        // 分
        String minutes = to.split(":")[1];
        // 秒
        String seconds = to.split(":")[2];

//        System.out.println("【年-月-日】 : " + from);
//        System.out.println("【时:分:秒】 : " + to);
//        System.out.println("【时】 : " + hour);
//        System.out.println("【分】 : " + minutes);
//        System.out.println("【秒】 : " + seconds);

        Integer intMinutes = Integer.parseInt(minutes);

        if ("00".equals(hour) && intMinutes < 30) { // 00:00:00 ~ 00:29:59 ==> 00:30:00 ~ 00:59:59
            newFrom = from + " 00:30:00";
            newTo = from + " 00:59:59";
        } else if ("00".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) { // 00:30:00 ~ 00:59:59 ==> 01:00:00 ~ 01:29:59
            newFrom = from + " 01:00:00";
            newTo = from + " 01:29:59";
        } else if ("01".equals(hour) && intMinutes < 30) { // 01:00:00 ~ 01:29:59 ==> 01:30:00 ~ 01:59:59
            newFrom = from + " 01:30:00";
            newTo = from + " 01:59:59";
        } else if ("01".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) { // 01:30:00 ~ 01:59:59 ==> 02:00:00 ~ 02:29:59
            newFrom = from + " 02:00:00";
            newTo = from + " 02:29:59";
        } else if ("02".equals(hour) && intMinutes < 30) { // 02:00:00 ~ 02:29:59 ==> 02:30:00 ~ 02:59:59
            newFrom = from + " 02:30:00";
            newTo = from + " 02:59:59";
        } else if ("02".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) { // 03:00:00 ~ 03:29:59 ==> 03:00:00 ~ 03:29:59
            newFrom = from + " 03:00:00";
            newTo = from + " 03:29:59";
        } else if ("03".equals(hour) && intMinutes < 30) {
            newFrom = from + " 03:30:00";
            newTo = from + " 03:59:59";
        } else if ("03".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 04:00:00";
            newTo = from + " 04:29:59";
        } else if ("04".equals(hour) && intMinutes < 30) {
            newFrom = from + " 04:30:00";
            newTo = from + " 04:59:59";
        } else if ("04".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 05:00:00";
            newTo = from + " 05:29:59";
        } else if ("05".equals(hour) && intMinutes < 30) {
            newFrom = from + " 05:30:00";
            newTo = from + " 05:59:59";
        } else if ("05".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 06:00:00";
            newTo = from + " 06:29:59";
        } else if ("06".equals(hour) && intMinutes < 30) {
            newFrom = from + " 06:30:00";
            newTo = from + " 06:59:59";
        } else if ("06".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 07:00:00";
            newTo = from + " 07:29:59";
        } else if ("07".equals(hour) && intMinutes < 30) {
            newFrom = from + " 07:30:00";
            newTo = from + " 07:59:59";
        } else if ("07".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 08:00:00";
            newTo = from + " 08:29:59";
        } else if ("08".equals(hour) && intMinutes < 30) {
            newFrom = from + " 08:30:00";
            newTo = from + " 08:59:59";
        } else if ("08".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 09:00:00";
            newTo = from + " 09:29:59";
        } else if ("09".equals(hour) && intMinutes < 30) {
            newFrom = from + " 09:30:00";
            newTo = from + " 09:59:59";
        } else if ("09".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 10:00:00";
            newTo = from + " 10:29:59";
        } else if ("10".equals(hour) && intMinutes < 30) {
            newFrom = from + " 10:30:00";
            newTo = from + " 10:59:59";
        } else if ("10".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 11:00:00";
            newTo = from + " 11:29:59";
        } else if ("11".equals(hour) && intMinutes < 30) {
            newFrom = from + " 11:30:00";
            newTo = from + " 11:59:59";
        } else if ("11".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 12:00:00";
            newTo = from + " 12:29:59";
        } else if ("12".equals(hour) && intMinutes < 30) {
            newFrom = from + " 12:30:00";
            newTo = from + " 12:59:59";
        } else if ("12".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 13:00:00";
            newTo = from + " 13:29:59";
        } else if ("13".equals(hour) && intMinutes < 30) {
            newFrom = from + " 13:30:00";
            newTo = from + " 13:59:59";
        } else if ("13".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 14:00:00";
            newTo = from + " 14:29:59";
        } else if ("14".equals(hour) && intMinutes < 30) {
            newFrom = from + " 14:30:00";
            newTo = from + " 14:59:59";
        } else if ("14".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 15:00:00";
            newTo = from + " 15:29:59";
        } else if ("15".equals(hour) && intMinutes < 30) {
            newFrom = from + " 15:30:00";
            newTo = from + " 15:59:59";
        } else if ("15".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 16:00:00";
            newTo = from + " 16:29:59";
        } else if ("16".equals(hour) && intMinutes < 30) {
            newFrom = from + " 16:30:00";
            newTo = from + " 16:59:59";
        } else if ("16".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 17:00:00";
            newTo = from + " 17:29:59";
        } else if ("17".equals(hour) && intMinutes < 30) {
            newFrom = from + " 17:30:00";
            newTo = from + " 17:59:59";
        } else if ("17".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 18:00:00";
            newTo = from + " 18:29:59";
        } else if ("18".equals(hour) && intMinutes < 30) {
            newFrom = from + " 18:30:00";
            newTo = from + " 18:59:59";
        } else if ("18".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 19:00:00";
            newTo = from + " 19:29:59";
        } else if ("19".equals(hour) && intMinutes < 30) {
            newFrom = from + " 19:30:00";
            newTo = from + " 19:59:59";
        } else if ("19".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 20:00:00";
            newTo = from + " 20:29:59";
        } else if ("20".equals(hour) && intMinutes < 30) {
            newFrom = from + " 20:30:00";
            newTo = from + " 20:59:59";
        } else if ("20".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 21:00:00";
            newTo = from + " 21:29:59";
        } else if ("21".equals(hour) && intMinutes < 30) {
            newFrom = from + " 21:30:00";
            newTo = from + " 21:59:59";
        } else if ("21".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 22:00:00";
            newTo = from + " 22:29:59";
        } else if ("22".equals(hour) && intMinutes < 30) {
            newFrom = from + " 22:30:00";
            newTo = from + " 22:59:59";
        } else if ("22".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            newFrom = from + " 23:00:00";
            newTo = from + " 23:29:59";
        } else if ("23".equals(hour) && intMinutes < 30) {
            newFrom = from + " 23:30:00";
            newTo = from + " 23:59:59";
        } else if ("23".equals(hour) && (intMinutes >= 30 && intMinutes <= 59)) {
            // 2024-06-02 23:36:26 ==> 2024-06-03 00:00:00 ~ 2024-06-03 00:29:29
            Date date = MyDateUtil.format2StringDate2Date(from);
            newFrom = MyDateUtil.addDay(date.toString()) + " 00:00:00";
            newTo = MyDateUtil.addDay(date.toString()) + " 00:29:59";
        }

        map.put("newFrom",newFrom);
        map.put("newTo",newTo);

        return map;
    }

    /**
     * 比较两个LocalDateTime的大小，如果：dateTime的时间戳 - 当前时间的时间戳 > 0，则返回true，否则返回false
     * @param dateTime elasticsearch_report表中end_date的值
     * @return
     */
    public static boolean compareLocalDateTime(LocalDateTime dateTime,Integer interval) {
//        log.debug("compareLocalDateTime endDate:{}",endDate);
        if (ObjectUtil.isNull(dateTime)) {
            return false;
        }

        // 计算两个时间点之间的差值
        Duration duration = Duration.between(dateTime, LocalDateTime.now());

        // 获取差值的分钟数
        long minutesDifference = duration.toMinutes();
        System.out.println("时间差：" + minutesDifference);
//        log.debug("compareLocalDateTime 时间差（分钟）:{}",minutesDifference);

        if (minutesDifference >= interval) {
            return true;
        }

        return false;
    }

    /**
     * 从文本中提取末次月经日期并转换为LocalDateTime
     * 时间部分默认设为00:00:00
     * @param prenatalCheckupInfo： 产检信息。包含末次月经日期的文本，如下：
     *        末次月经日期2025年08月04日，预产期：2026年04月08日，孕周：8 周；宫高： cm，腹围： cm；胎心bpm： ；胎位：  ；衔接：  ；水肿：有 ；宫锁：  ；血红蛋白：  ；尿蛋白：  。
     *        或者
     *        末次月经日期2025年7月10日，预产期：不详，孕周： 不详
     * @return 对应的LocalDateTime对象，若解析失败则返回null
     */
    public static LocalDateTime parseLastMenstrualDate(String prenatalCheckupInfo) {
        if (StringUtils.isBlank(prenatalCheckupInfo)) {
            return null;
        }
        prenatalCheckupInfo = prenatalCheckupInfo.trim();

        // 正则表达式：匹配"末次月经日期"后面跟随的日期
        /*
            适配格式：
                末次月经日期2025年08月04日
                末次月经日期2025年08月4日
                末次月经日期2025年8月4日
                末次月经日期2025年8月04日
         */
        String regex1 = "末次月经日期(\\d{4})年(\\d{1,2})月(\\d{1,2})日";
        /*
            适配格式：
                末次月经日期2025年08月04号
                末次月经日期2025年08月4号
                末次月经日期2025年8月4号
                末次月经日期2025年8月04号
         */
        String regex2 = "末次月经日期(\\d{4})年(\\d{1,2})月(\\d{1,2})号";

        Pattern pattern = null;
        Matcher matcher = null;
        LocalDate date = null;
        int year;
        int month;
        int day;

        try {
            int commaIndex = prenatalCheckupInfo.indexOf('，');
            if (commaIndex != -1) {
                String prefixMessage = prenatalCheckupInfo.substring(6,commaIndex);
                log.info("[解析月经日期]prefixMessage:{}",prefixMessage);
                if (prefixMessage.contains("日")) {
                    pattern = Pattern.compile(regex1);
                    matcher = pattern.matcher(prenatalCheckupInfo);
                } else {
                    pattern = Pattern.compile(regex2);
                    matcher = pattern.matcher(prenatalCheckupInfo);
                }
            }
        } catch (Exception e) {
            log.error("[解析月经日期]失败！原因：{}",e);
        }
        if (matcher.find()) {
            // 提取年、月、日
            year = Integer.parseInt(matcher.group(1));
            month = Integer.parseInt(matcher.group(2));
            day = Integer.parseInt(matcher.group(3));

            // 转换为LocalDateTime，时间部分默认为00:00:00
            return LocalDateTime.of(year, month, day, 0, 0, 0);
        }
        return null;
    }

}
